package common.server.http;

import common.server.utils.JsonUtils;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

/**
 *  HTTP HttpServletRequestWrapper
 * 
 * @author Administrator
 * @version [版本号, 2017/12/28 0028]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class HttpServletRequestWrapper
		extends javax.servlet.http.HttpServletRequestWrapper {

	/**
	 * 报文字符串
	 */
	private String reqBody;

	/**
	 * 报文json对象
	 */
	private JSONObject jsonBody;

	/**
	 * 自定义头部信息
	 */
	private Map<String, String> customHeaders;

	/**
	 * 内容长度
	 */
	private int contentLength;

	/**
	 * 内容长度
	 */
	private long contentLengthLong;

	/**
	 * @param request
	 */
	public HttpServletRequestWrapper(HttpServletRequest request) {
		super(request);
		this.customHeaders = new HashMap<>();
		ServletInputStream stream = null;
		try {
			stream = request.getInputStream();
			this.reqBody = IOUtils.toString(stream, "UTF-8").replaceAll(">\\s{1,}<", "><");
			if (StringUtils.isNotBlank(this.reqBody)) {
				this.jsonBody = JsonUtils.fromJson(this.reqBody);
			}
			LoggerFactory.getLogger(HttpServletRequestWrapper.class).debug(
					"Http ContentLength : {}", this.reqBody.getBytes().length);
			this.contentLength = super.getContentLength();
			this.contentLengthLong = super.getContentLengthLong();
		} catch (IOException e) {
			LoggerFactory.getLogger(HttpServletRequestWrapper.class)
					.error("Read Http Body Error:", e);
		} finally {
			IOUtils.closeQuietly(stream);
		}
	}

	@Override
	public BufferedReader getReader() throws IOException {
		return new BufferedReader(new InputStreamReader(getInputStream()));
	}

	@Override
	public ServletInputStream getInputStream() throws IOException {
		return new ServletInputStreamWrapper(reqBody.getBytes());
	}

	public void setReqBody(String reqBody) {
		this.reqBody = reqBody;
		LoggerFactory.getLogger(HttpServletRequestWrapper.class).debug(
				"Reset Http ContentLength : {}",
				this.reqBody.getBytes().length);
		this.contentLength = this.reqBody.getBytes().length;
		this.contentLengthLong = this.reqBody.getBytes().length;
		if (StringUtils.isNotBlank(this.reqBody)) {
			this.jsonBody = JsonUtils.fromJson(this.reqBody);
		}
	}

	/**
	 * 添header信息
	 * 
	 * @param name
	 * @param value
	 */
	public void addHeader(String name, String value) {
		this.customHeaders.put(name, value);
	}

	@Override
	public String getHeader(String name) {
		String headerValue = customHeaders.get(name);
		if (headerValue != null) {
			return headerValue;
		}
		return super.getHeader(name);
	}

	@Override
	public Enumeration<String> getHeaderNames() {
		Set<String> set = new HashSet<>(customHeaders.keySet());
		Enumeration<String> e = ((HttpServletRequest) getRequest())
				.getHeaderNames();
		while (e.hasMoreElements()) {
			String n = e.nextElement();
			set.add(n);
		}
		return Collections.enumeration(set);
	}

	public String getReqBody() {
		return reqBody;
	}

	public JSONObject getJsonBody() {
		return jsonBody;
	}

	public void setJsonBody(JSONObject jsonBody) {
		this.jsonBody = jsonBody;
	}

	@Override
	public int getContentLength() {
		return this.contentLength;
	}

	@Override
	public long getContentLengthLong() {
		return this.contentLengthLong;
	}
}
